package com.jcake.vimlike.internal.commands;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Region;

import com.jcake.vimlike.RegisterManager;
import com.jcake.vimlike.internal.CommandParser;
import com.jcake.vimlike.internal.registers.Register;

/**
 * <p>
 * <b>Yank command.</b>
 * </p>
 * 
 * <p>
 * Supported syntax
 * </p>
 * <ul>
 * <li><code>[register][count]yy</code>, <code>[register][count]Y</code> -
 * copies lines</li>
 * <li><code>[register][count]yap</code> - copies paragraphs</li>
 * <li><code>[register][count]yas</code> - copies sentences</li>
 * <li><code>[register][count]yaw</code> - copies words</li>
 * <li><code>[register][count]y$</code> - copies region from current position to the end of current + [count] line,</li>
 * <li><code>[register][count]y^</code> - copies region from beginning of current - [count] line to current position</li>
 * </ul>
 * 
 * 
 * @author Piotr Maj
 * 
 */
public class YankCommand extends AbstractRegisterCountCommand {

	private String[] fullCommands = { "yy", "Y", "yap", "yas", "yaw", "y$", "y^" };

	@Override
	protected String[] getFullCommands() {
		return fullCommands;
	}

	public void execute(String command) throws Exception {
		CommandParser parser = new CommandParser(command);
		Integer count = ((parser.getCount() != null) ? parser.getCount() : 1);
		Character register = parser.getRegister();
		String cmd = parser.getCommand();
		IDocument document = getDocument();

		Region regionForAction = new Region(-1, -1);
		Register.Type type = Register.Type.LINE_ORIENTED;

		int offset = getSelection().getOffset();
		if (cmd.equals("yy") || cmd.equals("Y")) {
			// yank lines
			regionForAction = findLines(getDocument(), offset, count);
		} else if (cmd.equals("yaw")) {
			// yank words
			regionForAction = findWords(getDocument(), offset, count);
			type = Register.Type.RANGE_ORIENTED;
		} else if (cmd.equals("yas")) {
			// yank sentences
			regionForAction = findSentences(getDocument(), offset, count);
			type = Register.Type.RANGE_ORIENTED;
		} else if (cmd.equals("yap")) {
			// yank paragraphs
			regionForAction = findParagraphs(getDocument(), offset, count);
			//type = Register.Type.RANGE_ORIENTED;
		} else if (cmd.equals("y$")) {
			regionForAction = findRegionToEndOfLine(getDocument(), offset, count);
		} else if (cmd.equals("y^")) {
			regionForAction = findRegionFromBeginingOfLinesBackToOffset(getDocument(), offset, count);
		}

		if (regionForAction.getOffset()  < 0 || regionForAction.getLength() < 0) {
			notice("Nothing yanked!");
			return;
		}

		String extractedText = document.get(regionForAction.getOffset(), regionForAction.getLength());

		RegisterManager.getInstance().updateRegister(RegisterManager.UNNAMED_REGISTER, extractedText, type);
		RegisterManager.getInstance().updateRegister('0', extractedText, type);
		if (register != null) {
			RegisterManager.getInstance().updateRegister(register, extractedText, type);
		}
	}

}
